home *** CD-ROM | disk | FTP | other *** search
- /*
- * ViewPorts.c
- *
- * Robert Dierkes, November 11, 1993
- *
- * Change History:
- *
- * 11/93 ??? New
- * 4/96 bob Updated #includes to support changed GX Library names.
- * Changed boolean to Boolean.
- * Changed fixed to Fixed.
- * Added the copyright info.
- *
- *
- * © Apple Computer, Inc. 1990 - 1996 All rights reserved
- *
- */
-
- #include <GXGraphics.h>
- #include "GraphicsLibraries.h"
- #include <GXEnvironment.h>
-
- #include "Object.h"
- #include "ViewPorts.h"
-
-
-
- /*----------------------*/
- /* Global Declarations */
- /*----------------------*/
- gxShape gObject,
- gLastObject,
- gFrame;
- Boolean gIsSquare,
- gShowFrame,
- gDoDither,
- gDoHalftone;
- long gPanesPerSide;
-
- /*------------------------------*/
- /* External Declarations */
- /*------------------------------*/
- extern Boolean gDoAnimation;
- extern Boolean gCyclePanes;
- extern long gNextCycle;
-
-
- void SetHalftone (gxViewPort vPort, Fixed angle, Fixed frequency, gxDotType method, gxRGBColor *pDotColor);
- void SetDitherOrHalftone (gxViewPort vPort, short row, short col);
- void SetMapping (gxViewPort vPort, short row, short col, Fixed xCenter, Fixed yCenter);
-
-
- static void
- SetHalftone (gxViewPort vPort,
- Fixed angle,
- Fixed frequency,
- gxDotType method,
- gxRGBColor *pDotColor)
- {
- gxHalftone tone;
-
- if (! gDoHalftone)
- return;
-
- tone.angle = angle;
- tone.frequency = frequency;
- tone.method = method;
- tone.tinting = gxLuminanceTint;
-
- tone.dotColor.space = gxRGBSpace;
- tone.dotColor.profile = nil;
- tone.dotColor.element.rgb = *pDotColor;
-
- tone.backgroundColor.space = gxRGBSpace;
- tone.backgroundColor.profile = nil;
- tone.backgroundColor.element.rgb.red =
- tone.backgroundColor.element.rgb.green =
- tone.backgroundColor.element.rgb.blue = (gxColorValue) 0xFFFF; /* white */
-
- tone.tintSpace = gxRGBSpace;
-
- GXSetViewPortHalftone (vPort, &tone);
- }
-
-
- static void
- SetDitherOrHalftone (gxViewPort vPort,
- short row,
- short col)
- {
- gxRGBColor dotColor;
-
- switch (row % kPaneRepeat)
- {
- case 0:
- switch (col % kPaneRepeat)
- {
- case 0:
- SetRBGColor (dotColor, 0xFFFF, 0, 0); /* Red */
- SetHalftone (vPort, IntToFixed (0), IntToFixed (4), gxRoundDot, &dotColor);
- break;
- case 1:
- IfSetViewPortDither (false, vPort, 1);
- break;
- case 2:
- SetRBGColor (dotColor, 0xFFFF, 45000, 0); /* Orange */
- SetHalftone (vPort, IntToFixed (45), IntToFixed (5), gxEllipticDot, &dotColor);
- break;
- case 3:
- IfSetViewPortDither (false, vPort, 1);
- break;
- }
- break;
-
- case 1:
- switch (col % kPaneRepeat)
- {
- case 0:
- IfSetViewPortDither (gDoDither, vPort, 2);
- break;
- case 1:
- SetRBGColor (dotColor, 60000, 60000, 0); /* Yellow */
- SetHalftone (vPort, IntToFixed (0), IntToFixed (5), gxSpiralDot, &dotColor);
- break;
- case 2:
- IfSetViewPortDither (gDoDither, vPort, 2);
- break;
- case 3:
- SetRBGColor (dotColor, 50000, 0, 50000); /* Lavender */
- SetHalftone (vPort, IntToFixed (135), IntToFixed (6), gxLineDot, &dotColor);
- break;
- }
- break;
-
- case 2:
- switch (col % kPaneRepeat)
- {
- case 0:
- SetRBGColor (dotColor, 0, 0xFFFF, 0); /* Green */
- SetHalftone (vPort, IntToFixed (45), IntToFixed (5), gxTriangleDot, &dotColor);
- break;
- case 1:
- IfSetViewPortDither (gDoDither, vPort, 3);
- break;
- case 2:
- SetRBGColor (dotColor, 0, 55000, 65000); /* Cyan */
- SetHalftone (vPort, IntToFixed (45), IntToFixed (4), gxSquareDot, &dotColor);
- break;
- case 3:
- IfSetViewPortDither (gDoDither, vPort, 3);
- break;
- }
- break;
-
- case 3:
- switch (col % kPaneRepeat)
- {
- case 0:
- IfSetViewPortDither (gDoDither, vPort, 4);
- break;
- case 1:
- SetRBGColor (dotColor, 0, 0, 0xFFFF); /* Blue */
- SetHalftone (vPort, IntToFixed (45), IntToFixed (6), gxLineDot, &dotColor);
- break;
- case 2:
- IfSetViewPortDither (gDoDither, vPort, 4);
- break;
- case 3:
- SetRBGColor (dotColor, 40000, 40000, 40000); /* Gray */
- SetHalftone (vPort, IntToFixed (0), IntToFixed (6), gxTriangleDot, &dotColor);
- break;
- }
- break;
- }
- }
-
-
- static void
- SetMapping (gxViewPort vPort,
- short row,
- short col,
- Fixed xCenter,
- Fixed yCenter)
- {
- gxMapping map;
-
- ResetMapping (&map);
-
- if ((row % kPaneRepeat == 0 || row % kPaneRepeat == 1) &&
- (col % kPaneRepeat == 2 || col % kPaneRepeat == 3))
- ScaleMapping (&map, fixed1, fixed1 >> 1, xCenter, yCenter);
- else
- if ((row % kPaneRepeat == 2 || row % kPaneRepeat == 3) &&
- (col % kPaneRepeat == 0 || col % kPaneRepeat == 1))
- ScaleMapping (&map, fixed1 >> 1, fixed1, xCenter, yCenter);
- else
- if ((row % kPaneRepeat == 1 || row % kPaneRepeat == 2) &&
- (col % kPaneRepeat == 1 || col % kPaneRepeat == 2))
- RotateMapping (&map, IntToFixed (30), xCenter, yCenter);
-
- GXSetViewPortMapping (vPort, &map);
- }
-
-
- void
- ChangeFrame (Rect *pBounds, long numCols, long numRows, Boolean showFrame, gxShape *pFrame)
- {
- register
- short r, c;
- register
- Fixed left,
- top,
- width,
- height;
- gxShape pane;
- Rect bounds;
-
- DisposeShapeAt (pFrame);
- if (! showFrame)
- return;
-
- /* Find width and height of each pane */
- bounds = *pBounds;
- InsetRect (&bounds, FixedToInt (kFrameThickness), FixedToInt (kFrameThickness));
- width = IntToFixed (bounds.right - bounds.left) / numCols;
- height = IntToFixed (bounds.bottom - bounds.top) / numRows;
-
- /* Start with the outside frame */
- *pFrame = GXNewShape (gxEmptyType);
-
- for (r = 0, top = kFrameThickness; r < numRows; r++)
- {
- for (c = 0, left = kFrameThickness; c < numCols; c++)
- {
- /* Add a pane inside the frame */
- pane = NewShape4 (gxRectangleType, left, top, left + width, top + height);
- GXInsetShape (pane, kFrameThickness);
- AddToShape (*pFrame, pane);
- GXDisposeShape (pane);
-
- left += width;
- }
- top += height;
- }
-
- /* Set other characteristics on the frame */
- SetShapeCommonColor (*pFrame, gxGray);
- GXSetShapeStyleAttributes (*pFrame, gxOutsideFrameStyle);
- GXSetShapeFill (*pFrame, gxClosedFrameFill);
- GXSetShapePen (*pFrame, kFrameThickness << 1);
-
- /* Make the frame a picture so the grow box can be added */
- GXSetShapeType (*pFrame, gxPictureType);
-
- /* Make a grow box in the lower left corner */
- pane = NewShape4 (gxRectangleType, IntToFixed (pBounds->right) - (kFrameThickness << 1),
- IntToFixed (pBounds->bottom) - (kFrameThickness << 1),
- IntToFixed (pBounds->right),
- IntToFixed (pBounds->bottom));
- SetShapeCommonColor (pane, steel);
- AddToPicture (*pFrame, pane, nil, nil, nil);
- GXDisposeShape (pane);
- }
-
-
- static void
- ChangeShapeViewPorts (WindowPtr pWindow, long numRows, long numCols,
- Boolean showFrame, gxShape object)
- {
- register
- short r, c;
- register
- gxViewPort *pViewPort,
- *p1stViewPort;
- Fixed width,
- height,
- left,
- top;
- gxShape clip;
- gxViewPort parent;
- gxTransform xForm;
- Rect bounds;
-
- if (numRows == 0 || numCols == 0)
- {
- DebugStr ("\pAddViewPortsToTransform: Number of rows or columns is zero");
- return;
- }
-
- /* Find width and height of each gxViewPort */
- bounds = pWindow->portRect;
- InsetRect (&bounds, FixedToInt (kFrameThickness), FixedToInt (kFrameThickness));
- width = IntToFixed (bounds.right - bounds.left) / numCols;
- height = IntToFixed (bounds.bottom - bounds.top) / numRows;
-
- /* Make a gxTransform */
- xForm = GXNewTransform ();
-
- /* Allocate space for viewPorts */
- p1stViewPort = pViewPort = (gxViewPort *) NewPtr (numRows * numCols * sizeof (gxViewPort));
- if (p1stViewPort == nil)
- {
- DebugStr ("\pAddViewPortsToTransform: NewPtr for viewPorts failed");
- return;
- }
-
- parent = GXGetWindowViewPort (pWindow);
-
- for (r = 0, top = kFrameThickness; r < numRows; r++, top += height)
- {
- for (c = 0, left = kFrameThickness; c < numCols; c++, left += width, pViewPort++)
- {
- /* Make a new gxViewPort and set its clip and gxMapping */
- *pViewPort = GXNewViewPort (gxScreenViewDevices);
- GXSetViewPortParent (*pViewPort, parent);
-
- /* Make and set the gxViewPort's clip */
- clip = NewShape4 (gxRectangleType, left, top, left + width, top + height);
- if (showFrame)
- GXInsetShape (clip, kFrameThickness);
- GXSetViewPortClip (*pViewPort, clip);
- GXDisposeShape (clip);
-
- /* Set the dither or gxHalftone and gxMapping */
- SetDitherOrHalftone (*pViewPort, r, c);
- SetMapping (*pViewPort, r, c, left + (width >> 1), top + (height >> 1));
-
- if (r == 0 && c == 0)
- /* Set the gxTransform's first gxViewPort */
- GXSetTransformViewPorts (xForm, 1, pViewPort);
- else
- /* Add successive viewPorts */
- AddToTransformViewPort (xForm, *pViewPort);
- }
- }
-
- /* Set the object gxShape's gxTransform with all the gxViewPort */
- GXSetShapeTransform (object, xForm);
- GXDisposeTransform (xForm);
- }
-
-
- void
- InitializeViewPortGlobals (void)
- {
- gShowFrame = true;
- gDoAnimation = false;
- gDoDither = true;
- gDoHalftone = true;
- gIsSquare = true;
- gObject = nil;
- gFrame = nil;
- gPanesPerSide = kInitialPanesPerSide;
- gCyclePanes = false;
- gNextCycle = 0;
- }
-
-
- void
- ChangeViewPorts (WindowPtr pWindow)
- {
- ChangeShapeViewPorts (pWindow, gPanesPerSide, gPanesPerSide, gShowFrame, gObject);
- ChangeFrame (&pWindow->portRect, gPanesPerSide, gPanesPerSide, gShowFrame, &gFrame);
- }
-
-
- void
- InitializeViewPorts (WindowPtr pWindow)
- {
- InitializeObject (gIsSquare, kObjectWidth, kObjectHeight, &gObject, &gLastObject);
- ChangeViewPorts (pWindow);
- }
-
- void
- DisposeViewPorts (WindowPtr pWindow)
- {
- gxViewPort parent,
- *p1stChild,
- *pChild;
- long childCount;
-
- DisposeShapeAt (&gObject);
- DisposeShapeAt (&gLastObject);
- DisposeShapeAt (&gFrame);
-
- if (parent = GXGetWindowViewPort (pWindow))
- {
- if (childCount = GXGetViewPortChildren (parent, nil))
- {
- if (p1stChild = pChild = (gxViewPort *) NewPtrClear (childCount * sizeof (gxViewPort)))
- {
- (void) GXGetViewPortChildren (parent, p1stChild);
- while (childCount--)
- GXDisposeViewPort (*pChild++);
- DisposePtr ((Ptr) p1stChild);
- GXDisposeViewPort (parent);
- }
- else
- DebugStr ("\pDisposeViewPorts: NewPtrClear failed");
- }
- else
- DebugStr ("\pDisposeViewPorts: Parent gxViewPort has no children");
- }
- else
- DebugStr ("\pDisposeViewPorts: Window has no gxViewPort");
- }
-